home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / lcsrc.arc / KEY_INT.ASM < prev    next >
Assembly Source File  |  1985-04-18  |  7KB  |  347 lines

  1.     page    60,132
  2.  
  3. title IBM PC Communications I/O Routines -- Curt Klinsing
  4.  
  5. interrupts     segment at 0h
  6.         org    9h*4
  7. keyboard_int    label    word
  8. interrupts    ends
  9.  
  10.  
  11.     include dos.mac
  12.  
  13.  
  14.     IF    LPROG
  15. X    EQU    6        ;OFFSET OF ARGUMENTS
  16.     ELSE
  17. X    EQU    4        ;OFFSET OF ARGUMENTS
  18.     ENDIF
  19.  
  20.  
  21.  
  22.  
  23.     PSEG
  24.  
  25. ;
  26. ;
  27. ;A set    of Lattice C callable functions    to support
  28. ;interrupt driven character I/O on the    IBM PC.    Input
  29. ;is buffered, output is polled.
  30. ;
  31. public    key_intercept    ;initialize the    comm port,
  32. public    key_nointercept    ;remove    initialization,
  33. public    key_intbcnt    ;returns count of rcv chars,
  34. public    key_intbread    ;get one char from buffer,
  35. public    key_intbflush    ;flush input buffer,
  36.  
  37.  
  38.  
  39. ;
  40. FALSE    EQU    0
  41. TRUE    EQU    NOT FALSE
  42. ;
  43. ;
  44. ;    MISCELLANEOUS EQUATES
  45. ;
  46. BUFSIZ    EQU    512    ;Max NUMBER OF CHARS
  47. SetIntVect  EQU    25H    ;SET INTERRUPT VECTOR FUNCTION NUMBER
  48.  
  49. ;
  50. ;    DUMP BUFFER, COUNT AND POINTER.     
  51. ;
  52. CIRC_BUF     DB    BUFSIZ DUP(?)    ;ALLOW 512 MaxIMUM BUFFERED CHARACTERS
  53. BUF_TOP        EQU    $ - 1        ;KEEP TRACK OF THE TOP OF THE BUFFER
  54. CIRC_TOP    DW    BUF_TOP        ;
  55. ;
  56. CIRC_IN     DW    OFFSET CIRC_BUF    ;POINTER TO LAST CHAR. PLACED IN BUFFER
  57. CIRC_CUR DW    OFFSET CIRC_BUF    ;POINTER TO NEXT CHAR. TO BE RETRIEVED FROM
  58.                 ; BUFFER
  59. CIRC_CT    DW    0        ;COUNT OF CHARACTERS USED IN BUFFER
  60. junk    dw    0,0,0
  61. old_keyboard_int   dw 0,0,0,0    ; storage for old keyboard vector
  62. junk2    dw    0,0,0
  63.  
  64.  
  65. ;--------------------------------------------------------------
  66. ;
  67. ; name        key_intercept - intercept hardware key interrupt
  68. ;
  69. ; synopsis    key_intercept();
  70. ;
  71. ; description    Intercepts the hardware keyboard interrupt.  You can
  72. ;        use this routine to gain absolute control over the 
  73. ;        keyboard.  The disadvantage is that you have to work
  74. ;        with scan codes directly, not nice ascii characters.
  75. ;        Up to 512 scan codes are buffered.
  76. ;
  77. ; notes
  78. ;        The key_nointercept routine MUST be called before
  79. ;        leaving your program, or the machine will hang.
  80. ;
  81. ;        You must not attempt to use any other routine that
  82. ;        reads the keyboard, or your program will hang.  This
  83. ;        routine absolutely intercepts the keyboard.
  84. ;
  85. ;        You are in control of the keyboard, but that means that
  86. ;        it is your responsibility to manage the state of the
  87. ;        shift keys, the caps lock, and numlock keys and any other
  88. ;        command keys, like the control key.
  89. ;
  90. ;        Each key returns two scan codes, one when pressed, one
  91. ;        when released.  The code returned when the key is pressed
  92. ;        is called a MAKE code, the one returned when a key is
  93. ;        released is called a BREAK code.  The BREAK code is 
  94. ;        the same as the make code, except that the high order bit
  95. ;        is set in the BREAK code.
  96. ;
  97. ;---------------------------------------------------------------------     
  98.  
  99.  
  100.  
  101.     IF    LPROG
  102. key_intercept    PROC    FAR
  103.     ELSE
  104. key_intercept    PROC    NEAR
  105.     ENDIF
  106.  
  107.  
  108.  
  109.     push    bp
  110.     cli
  111.     push    ds
  112.  
  113.     assume ds:interrupts
  114.  
  115.     mov    ax,interrupts
  116.     mov    ds,ax
  117.     mov    ax,keyboard_int
  118.     mov    old_keyboard_int,ax
  119.     mov    ax,keyboard_int[2]
  120.     mov    old_keyboard_int[2],ax
  121.     mov    ax,offset IntHdlr
  122.     mov    keyboard_int,ax
  123.     mov    keyboard_int[2],cs
  124.  
  125.     sti
  126.     pop    ds
  127.     pop    bp
  128.     ret
  129.  
  130. key_intercept endp
  131.  
  132.  
  133.  
  134. ;------------------------------------------------------------------------
  135. ; name        key_nointercept - remove keyboard interception
  136. ;
  137. ; synopsis    VOID key_nointercept()
  138. ;
  139. ; description    Removes    the interrupt structure    installed by key_intercept.
  140. ;        Must be done before passing control to DOS, else your 
  141. ;        machine will hang.
  142. ;-----------------------------------------------------------------------
  143.  
  144.     IF    LPROG
  145. key_nointercept    PROC    FAR
  146.     ELSE
  147. key_nointercept    PROC    NEAR
  148.     ENDIF
  149.  
  150.  
  151.     push    ds
  152.     assume    ds:interrupts
  153.     cli
  154.     mov    ax,interrupts
  155.     mov    ds,ax
  156.     mov    ax,old_keyboard_int
  157.     mov    keyboard_int,ax
  158.     mov    ax,old_keyboard_int[2]
  159.     mov    keyboard_int[2],ax
  160.     pop    ds
  161.     sti
  162.     ret
  163.  
  164. key_nointercept endp
  165.  
  166.  
  167.  
  168.  
  169.  
  170. ;----------------------------------------------------------
  171. ; name        key_intbcnt - Return # chars in interrupt buffer
  172. ;
  173. ; synopsis    count = key_intbcnt();
  174. ;
  175. ; description    Returns the number of scan codes available in the
  176. ;        keyboard intercept interrupt buffer.
  177. ;
  178. ; notes        Call this to make sure that there are keystrokes
  179. ;        available before attempting to read a code out of
  180. ;        the buffer.  If there are no codes available, DO NOT
  181. ;        attempt to read the buffer.
  182. ;
  183. ;--------------------------------------------------------------------  
  184. ;
  185.  
  186.  
  187.     IF    LPROG
  188. key_intbcnt    PROC    FAR
  189.     ELSE
  190. key_intbcnt    PROC    NEAR
  191.     ENDIF
  192.  
  193.     push    bp
  194.     push    ds        ; save data segment
  195.     push    cs
  196.     pop    ds        ; move code seg    addr to    data seg reg
  197.     mov    ax,circ_ct
  198.     pop    ds
  199.     pop    bp
  200.     ret
  201. key_intbcnt    endp
  202.  
  203.  
  204.  
  205.  
  206.  
  207. ;----------------------------------------------------------------
  208. ;
  209. ; name        key_intbflush - Flush the interrupt buffer.
  210. ;
  211. ; synopsis    VOID key_intbflush()
  212. ;
  213. ; description    Flushes any key strokes in the keyboard interrupt
  214. ;        intercept buffer.
  215. ;
  216. ;------------------------------------------------------------------
  217.  
  218.  
  219.     IF    LPROG
  220. key_intbflush    PROC    FAR
  221.     ELSE
  222. key_intbflush    PROC    NEAR
  223.     ENDIF
  224.  
  225.  
  226.     push    bp
  227.     push    ds        ; save data reg
  228.     push    cs
  229.     pop    ds        ; move code seg    addr to    data seg reg.
  230.     mov    bx,offset circ_buf
  231.     mov    circ_in,bx    
  232.     mov    circ_cur,bx
  233.     xor    ax,ax
  234.     mov    circ_ct,ax
  235.     pop    ds
  236.     pop    bp
  237.     ret
  238. key_intbflush endp
  239.  
  240.  
  241.  
  242. ;------------------------------------------------------
  243. ;
  244. ; name        key_intbread - get a char from the input buffer.
  245. ;
  246. ; synopsis    ch = key_intbread();
  247. ;
  248. ; description    returns the next character from the keyboard
  249. ;        interrupt intercept buffer. Assumes you have called
  250. ;        key_intbcnt to see if there are any characters to get.
  251. ;
  252. ; notes:
  253. ;        Will probably crash if called when the buffer is
  254. ;        empty.  Call key_intbcnt first to see if there is
  255. ;        anything available to read !!!!!!!!
  256. ;
  257. ;--------------------------------------------------------------------
  258.  
  259.  
  260.  
  261.     IF    LPROG
  262. key_intbread    PROC    FAR
  263.     ELSE
  264. key_intbread    PROC    NEAR
  265.     ENDIF
  266.  
  267.  
  268.     push    bp
  269.     push    ds        ; save data reg
  270.     push    cs
  271.     pop    ds        ; move code seg    addr to    data seg reg.
  272.     mov    bx,circ_cur
  273.     xor    ax,ax
  274.     mov    al,[bx]        ;get next char from circ_buf
  275.     DEC    circ_ct        ;decrement circ_buf COUNT
  276.     CMP    bx,circ_top    ;ARE WE    AT THE TOP OF THE circ_buf?
  277.     JZ    reset_cur    ;JUMP IF SO
  278.     INC    bx        ;ELSE, BUMP PTR
  279.     JMP SHORT upd_cur
  280. reset_cur:
  281.     mov    bx,OFFSET circ_buf    ;RESET circ_in TO BOTTOM OF BUF.
  282. upd_cur:
  283.     mov    circ_cur,bx        ;SAVE NEW PTR
  284.     pop    DS        ;GET BACK ENTERING DS
  285.     pop    bp
  286.     ret
  287. key_intbread endp
  288. ;
  289.  
  290.  
  291. kb_ctl    equ    61h
  292.  
  293. ;
  294. IntHdlr proc far
  295.     CLI
  296.     push    cx
  297.     push    dx
  298.     push    bx
  299.     push    ax
  300.     push    ds
  301.     mov    ax,cs        ;get cur code segment
  302.     mov    ds,ax        ; and set it as    data segment
  303.     mov    bx,circ_in    ;GET circ_buf IN PTR
  304.  
  305.  
  306.     in    al,60h
  307.     push    ax        ; save scan code
  308.     in    al,kb_ctl
  309.     mov    ah,al
  310.     or    al,80h        ; set "reset" bit
  311.     out    kb_ctl,al
  312.     xchg    ah,al
  313.     out    kb_ctl,al
  314.     pop    ax
  315.     mov    ah,al
  316.  
  317. ck_full:
  318.     cmp    circ_ct,BUFSIZ    ;SEE IF    circ_buf ALREADY FULL
  319.     jz    clnup        ; JUMP IF SO, DO NOT PLACE CHARACTER IN    BFR
  320. savch:                
  321.     mov    [bx],AL        ;SAVE NEW CHARACTER IN circ_buf
  322.     inc    circ_ct        ;BUMP circ_buf COUNT
  323.     CMP    bx,circ_top    ;ARE WE    AT THE TOP OF THE circ_buf?
  324.     JZ    reset_in    ;JUMP IF SO
  325.     inc    bx        ;ELSE, BUMP PTR
  326.     JMP     SHORT into_buf
  327. reset_in:
  328.     mov    bx,OFFSET circ_buf    ;RESET circ_in TO BOTTOM OF BUF.
  329. into_buf:
  330.     mov    circ_in,bx        ;SAVE NEW PTR
  331. clnup:
  332.     mov    AL,20h
  333.     OUT    020h,AL        ;ISSUE SPECIFIC    EOI FOR    8259
  334.     pop    ds        ;GET BACK ENTERING DS
  335.     pop    ax
  336.     pop    bx
  337.     pop    dx
  338.     pop    cx
  339.     sti
  340.     iret
  341.  
  342. IntHdlr endp
  343.  
  344.     endps
  345.     end
  346.